#include "PieceGeneratorModel.h"
#include "IPieceModel.h"
#include "OPieceModel.h"
#include "TPieceModel.h"
#include "JPieceModel.h"
#include "LPieceModel.h"
#include "SPieceModel.h"
#include "ZPieceModel.h"
#include "UpdatePreviewNetworkEvent.h"
#include "AddPieceNetworkEvent.h"

#include <cstdlib>

PieceGeneratorModel::PieceGeneratorModel(PlayersPtr players, unsigned int widthOfWell)
    : players(players), widthOfWell(widthOfWell)
{
    fillNextPieces();
}

PieceGeneratorModel::~PieceGeneratorModel()
{
}

PieceModel* PieceGeneratorModel::createRandomPiece(const Position& position)
{
    switch (rand() % 7)
    {
    case 0:
        return new IPieceModel(position);
    case 1:
        return new LPieceModel(position);
    case 2:
        return new JPieceModel(position);
    case 3:
        return new SPieceModel(position);
    case 4:
        return new ZPieceModel(position);
    case 5:
        return new TPieceModel(position);
    case 6:
        return new OPieceModel(position);
    default:
        return new IPieceModel(position);
    }
}

PieceModel* PieceGeneratorModel::getNextPieceFor(int playerId)
{
    PieceModel* result = nextPieces[playerId];
    Position position = players->getPlayerPosition(playerId, widthOfWell);
    Color color = players->getPlayerColor(playerId);
    nextPieces[playerId] = createRandomPiece(position);
    addChangeEvent(new AddPieceNetworkEvent(result->getId(), position, color));
    addChangeEvent(new UpdatePreviewNetworkEvent(nextPieces[playerId]->getLocalPositions(), color), playerId);
    return result;
}

void PieceGeneratorModel::fillNextPieces()
{
    PlayerIds playerIds = players->getPlayerIds();
    for (PlayerIds::iterator it = playerIds.begin(); it != playerIds.end(); ++it)
    {
        Position position = players->getPlayerPosition(*it, widthOfWell);
        PieceModel* nextPiece = createRandomPiece(position);
        nextPieces[*it] = nextPiece;
    }
}

